package com.demo2do.fms.admin.dao.business;

import java.math.BigDecimal;
import java.util.Map;

import javax.persistence.ParameterMode;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;
import org.hibernate.procedure.ProcedureCall;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.GenericJdbcSupport;
import com.demo2do.fms.entity.business.shipment.DispatchOrder;
import com.demo2do.fms.entity.business.shipment.TransportCost;

/**
 *
 * @author Ark
 *
 */
@Repository("dispatchOrderDaoSupport")
public class DispatchOrderDaoSupport {
    
    private static final Logger logger = LoggerFactory.getLogger(DispatchOrderDaoSupport.class);
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Autowired
    private GenericJdbcSupport genericJdbcSupport;

    /**
     * 生成派车单
     * 
     * @param dispatchOrder
     * @param loadNumber
     * @param oilTypeId
     * @param driverNumber
     * @param operatorId
     * @param operatorName
     * @return
     */
    public Long generate(DispatchOrder dispatchOrder, String loadNumber, Long oilTypeId, Integer driverNumber, Long operatorId, String operatorName) {
        
        oilTypeId = oilTypeId != null ? oilTypeId : 0L;
        Long firstViceDriverId = dispatchOrder.getFirstViceDriverId() != null ? dispatchOrder.getFirstViceDriverId() : 0L;
        String remarks = StringUtils.isNotBlank(dispatchOrder.getRemarks()) ? dispatchOrder.getRemarks() : "";
        
        logger.info("#generate() - generate dispatch order's parameters is [loadNumber={}, dispatchOrderId={}, userId={}, userName={}, organizationId={}, oilTypeId={}, driverNumber={}, mainDriverId={}, firstViceDriverId={}, secondViceDriverId={}, thirdViceDriverId={}, "
                                                                         + "fullLoadNumber={}, dispatchOrderCode={}, otherFeeAuditor={}, remarks={}]", 
                                                                            loadNumber, dispatchOrder.getId(), operatorId, operatorName, dispatchOrder.getOrganizationId(),
                                                                            oilTypeId, driverNumber, dispatchOrder.getMainDriverId(), firstViceDriverId, 0L, 0L, 
                                                                            dispatchOrder.getFullLoadNumber(), dispatchOrder.getCode(), "", remarks);
        
        // 1. get current session
        Session session = genericDaoSupport.getCurrentSession();
        
        // 2. construct procedure
        ProcedureCall call = session.createStoredProcedureCall("SP_CREATE_DISPATH_ORDER_NEW2");
        
        call.registerParameter("p_loadNumber", String.class, ParameterMode.IN).bindValue(loadNumber);
        call.registerParameter("p_dispatchOrderId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getId());
        call.registerParameter("p_userId", Long.class, ParameterMode.IN).bindValue(operatorId);
        call.registerParameter("p_userName", String.class, ParameterMode.IN).bindValue(operatorName);
        call.registerParameter("p_organizationId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getOrganizationId());
        call.registerParameter("p_oilTypeId", Long.class, ParameterMode.IN).bindValue(oilTypeId);
        call.registerParameter("p_driverNumber", Integer.class, ParameterMode.IN).bindValue(driverNumber);
        call.registerParameter("p_mainDriverId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getMainDriverId());
        call.registerParameter("p_firstViceDriverId", Long.class, ParameterMode.IN).bindValue(firstViceDriverId);
        call.registerParameter("p_secondViceDriverId", Long.class, ParameterMode.IN).bindValue(0L);
        call.registerParameter("p_thirdViceDriverId", Long.class, ParameterMode.IN).bindValue(0L);
        call.registerParameter("p_fullLoadNumber", Integer.class, ParameterMode.IN).bindValue(dispatchOrder.getFullLoadNumber());
        call.registerParameter("p_dispatchOrderCode", String.class, ParameterMode.IN).bindValue(dispatchOrder.getCode());
        call.registerParameter("p_otherFeeAuditor", String.class, ParameterMode.IN).bindValue("");
        call.registerParameter("p_remarks", String.class, ParameterMode.IN).bindValue(remarks);
        call.registerParameter("r_dispatchOrderId", Long.class, ParameterMode.OUT);
        
        // 3. do execute
        Long dispatchOrderId = (Long) call.getOutputs().getOutputParameterValue("r_dispatchOrderId");
        
        return dispatchOrderId;
        
    }
    
    /**
     * 生成修改派车单
     * 
     * @param dispatchOrder
     * @param loadNumber
     * @param oilTypeId
     * @param driverNumber
     * @param roadFee
     * @param adjustmentDistance
     * @param otherFeeSum
     * @param operatorId
     * @param operatorName
     * @return
     */
    public Long generateUpdate(DispatchOrder dispatchOrder, String loadNumber, Long oilTypeId, Integer driverNumber, BigDecimal roadFee, BigDecimal adjustmentDistance, BigDecimal otherFeeSum, Long operatorId, String operatorName,String otherFeeAuditor) {
        
        oilTypeId = oilTypeId != null ? oilTypeId : 0L;
        Long firstViceDriverId = dispatchOrder.getFirstViceDriverId() != null ? dispatchOrder.getFirstViceDriverId() : 0L;
        String remarks = StringUtils.isNotBlank(dispatchOrder.getRemarks()) ? dispatchOrder.getRemarks() : "";
        otherFeeAuditor = StringUtils.isNotBlank(otherFeeAuditor) ? otherFeeAuditor : "";

        // handle null value
        String distanceAdjustRemark = StringUtils.isNotBlank(dispatchOrder.getDistanceAdjustRemark()) ? dispatchOrder.getDistanceAdjustRemark() : "";
        String distanceAdjustType = StringUtils.isNotBlank(dispatchOrder.getDistanceAdjustType()) ? dispatchOrder.getDistanceAdjustType() : "";
        
        logger.info("#generateUpdate() - generate dispatch order's parameters is [loadNumber={}, dispatchOrderId={}, userId={}, userName={}, organizationId={}, otherFeeAuditor={}, oilTypeId={}, driverNumber={}, mainDriverId={}, firstViceDriverId={}, secondViceDriverId={}, thirdViceDriverId={}, "
                                                                         + "fullLoadNumber={}, dispatchOrderCode={}, otherFeeAuditor={}, remarks={}, roadFee={}, adjustmentDistance={}, distanceAdjustType={}, distanceAdjustRemark={}, otherFeeSum={}]", 
                                                                            loadNumber, dispatchOrder.getId(), operatorId, operatorName, dispatchOrder.getOrganizationId(),
                                                                            oilTypeId, driverNumber, dispatchOrder.getMainDriverId(), firstViceDriverId, 0L, 0L, 
                                                                            dispatchOrder.getFullLoadNumber(), dispatchOrder.getCode(), "", remarks,
                                                                            roadFee, adjustmentDistance, distanceAdjustType, distanceAdjustRemark, otherFeeSum);
        
        // 1. get current session
        Session session = genericDaoSupport.getCurrentSession();
        
        // 2. construct procedure
        ProcedureCall call = session.createStoredProcedureCall("SP_CREADIFY_DISPATCH_ORDER");
        
        call.registerParameter("p_loadNumber", String.class, ParameterMode.IN).bindValue(loadNumber);
        call.registerParameter("p_dispatchOrderId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getId());
        call.registerParameter("p_userId", Long.class, ParameterMode.IN).bindValue(operatorId);
        call.registerParameter("p_userName", String.class, ParameterMode.IN).bindValue(operatorName);
        call.registerParameter("p_organizationId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getOrganizationId());
        call.registerParameter("p_oilTypeId", Long.class, ParameterMode.IN).bindValue(oilTypeId);
        call.registerParameter("p_driverNumber", Integer.class, ParameterMode.IN).bindValue(driverNumber);
        call.registerParameter("p_mainDriverId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getMainDriverId());
        call.registerParameter("p_firstViceDriverId", Long.class, ParameterMode.IN).bindValue(firstViceDriverId);
        call.registerParameter("p_secondViceDriverId", Long.class, ParameterMode.IN).bindValue(0L);
        call.registerParameter("p_thirdViceDriverId", Long.class, ParameterMode.IN).bindValue(0L);
        call.registerParameter("p_fullLoadNumber", Integer.class, ParameterMode.IN).bindValue(dispatchOrder.getFullLoadNumber());
        call.registerParameter("p_dispatchOrderCode", String.class, ParameterMode.IN).bindValue(dispatchOrder.getCode());
        call.registerParameter("p_otherFeeAuditor", String.class, ParameterMode.IN).bindValue(otherFeeAuditor);
        call.registerParameter("p_remarks", String.class, ParameterMode.IN).bindValue(remarks);
        
        
        //added by Leon.Huang    
        call.registerParameter("p_roadBridgeFee", BigDecimal.class, ParameterMode.IN).bindValue(roadFee);
        call.registerParameter("p_adjustedDistance", BigDecimal.class, ParameterMode.IN).bindValue(adjustmentDistance);
        call.registerParameter("p_distanceAdjustType", String.class, ParameterMode.IN).bindValue(distanceAdjustType);
        call.registerParameter("p_distanceAdjustRemark", String.class, ParameterMode.IN).bindValue(distanceAdjustRemark);
        call.registerParameter("p_otherFeeSum", BigDecimal.class, ParameterMode.IN).bindValue(otherFeeSum);
        
        // out param as last param
        call.registerParameter("r_dispatchOrderId", Long.class, ParameterMode.OUT);
        
        // 3. do execute
        Long dispatchOrderId = (Long) call.getOutputs().getOutputParameterValue("r_dispatchOrderId");
        
        return dispatchOrderId;
        
    }
    
    /**
            * 维护派车单
     * 
     * @param dispatchOrder
     * @param mainDriverId
     * @param firstViceDriverId
     * @param driverNumber
     * @param facilityDistance
     * @param transportCost
     * @param otherFeeSum
     */
    public void edit(DispatchOrder dispatchOrder, Long mainDriverId, Long firstViceDriverId, int driverNumber, BigDecimal facilityDistance, TransportCost transportCost, BigDecimal otherFeeSum) {
        
        String otherFeeAuditor = StringUtils.isNotBlank(transportCost.getOtherFeeAuditor()) ? transportCost.getOtherFeeAuditor() : "";
        String distanceAdjustRemark = StringUtils.isNotBlank(dispatchOrder.getDistanceAdjustRemark()) ? dispatchOrder.getDistanceAdjustRemark() : "";
        String distanceAdjustType = StringUtils.isNotBlank(dispatchOrder.getDistanceAdjustType()) ? dispatchOrder.getDistanceAdjustType() : "";
        
        logger.info("#edit() - edit dispatch order's parameters is " +
                    "[dispatchOrderId={}, userId={}, organizationId={}, oilTypeId={}, driverNumber={}, mainDriverId={}, firstViceDriverId={}, secondViceDriverId={}, thirdViceDriverId={}, " +
                    "fullLoadNumber={}, otherFeeAuditor={}, remarks={}, roadBridgeFee={}, facilityDistance={}, distanceAdjustType={}, distanceAdjustRemark={}, otherFeeSum={}]", 
                    dispatchOrder.getId(), dispatchOrder.getLastOperatorId(), dispatchOrder.getOrganizationId(),
                    transportCost.getOilTypeId(), driverNumber, mainDriverId, firstViceDriverId, 0L, 0L, 
                    dispatchOrder.getFullLoadNumber(), otherFeeAuditor, dispatchOrder.getRemarks(), transportCost.getRoadFee(), facilityDistance,
                    distanceAdjustType, distanceAdjustRemark, otherFeeSum);
        
        // 1. get current session
        Session session = genericDaoSupport.getCurrentSession();
        
        // 2. construct procedure
        ProcedureCall call = session.createStoredProcedureCall("SP_MODIFY_DISPATH_ORDER_NEW2");
        
        call.registerParameter("p_dispatchOrderId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getId());;
        call.registerParameter("p_userId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getLastOperatorId());
        call.registerParameter("p_organizationId", Long.class, ParameterMode.IN).bindValue(dispatchOrder.getOrganizationId());
        call.registerParameter("p_oilTypeId", Long.class, ParameterMode.IN).bindValue(transportCost.getOilTypeId());
        call.registerParameter("p_driverNumber", Integer.class, ParameterMode.IN).bindValue(driverNumber);
        call.registerParameter("p_mainDriverId", Long.class, ParameterMode.IN).bindValue(mainDriverId);
        call.registerParameter("p_firstViceDriverId", Long.class, ParameterMode.IN).bindValue(firstViceDriverId);
        call.registerParameter("p_secondViceDriverId", Long.class, ParameterMode.IN).bindValue(0L);
        call.registerParameter("p_thirdViceDriverId", Long.class, ParameterMode.IN).bindValue(0L);
        call.registerParameter("p_fullLoadNumber", Integer.class, ParameterMode.IN).bindValue(dispatchOrder.getFullLoadNumber());
        call.registerParameter("p_otherFeeAuditor", String.class, ParameterMode.IN).bindValue(otherFeeAuditor);
        call.registerParameter("p_remarks", String.class, ParameterMode.IN).bindValue(dispatchOrder.getRemarks());
        call.registerParameter("p_roadBridgeFee", BigDecimal.class, ParameterMode.IN).bindValue(transportCost.getRoadFee());
        call.registerParameter("p_facilityDistance", BigDecimal.class, ParameterMode.IN).bindValue(facilityDistance);
        call.registerParameter("p_distanceAdjustType", String.class, ParameterMode.IN).bindValue(distanceAdjustType);
        call.registerParameter("p_distanceAdjustRemark", String.class, ParameterMode.IN).bindValue(distanceAdjustRemark);
        call.registerParameter("p_otherFeeSum", BigDecimal.class, ParameterMode.IN).bindValue(otherFeeSum);
        
        // 3. do execute
        call.execute();
        
    }
    
    /**
     * 删除派车单
     * 
     * @param dispatchOrderId
     * @param operatorId
     * @param operatorName
     */
    public void disable(Long dispatchOrderId, Long operatorId, String operatorName) {
        
        logger.info("#disable() - disable dispatchOrder's param is [dispatchOrderId={}, userId={}, userName={}]", dispatchOrderId, operatorId, operatorName);
        
        // 1. get current session
        Session session = genericDaoSupport.getCurrentSession();
        
        // 2. construct procedure
        ProcedureCall call = session.createStoredProcedureCall("SP_DELETE_DISPATH_ORDER_NEW2");
        call.registerParameter("p_dispatchOrderId", Long.class, ParameterMode.IN).bindValue(dispatchOrderId);;
        call.registerParameter("p_userId", Long.class, ParameterMode.IN).bindValue(operatorId);
        call.registerParameter("p_userName", String.class, ParameterMode.IN).bindValue(operatorName);
        
        // 3. do execute
        call.execute();
        
    }
    
    /**
     * 派车单中商品车详情(FC_GET_CARSUMMARY)
     * 
     * @param dispatchOrderId
     * @return
     */
    public String getCarSummary(Long dispatchOrderId) {
    
        String sentence = "SELECT FC_GET_CARSUMMARY(:dispatchOrderId) AS summary FROM DUAL";
        
        Map<String, Object> result = genericJdbcSupport.queryForObject(sentence, "dispatchOrderId", dispatchOrderId);
        return (String) result.get("summary");
    	
    }
    
}